/*
 Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies)
 Copyright (C) 2014 Sony Computer Entertainment Inc.

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License as published by the Free Software Foundation; either
 version 2 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.

 You should have received a copy of the GNU Library General Public License
 along with this library; see the file COPYING.LIB.  If not, write to
 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 Boston, MA 02110-1301, USA.
 */
#include "config.h"
#include "AcagiTile.h"

#if USE(ACCELERATED_COMPOSITING) && USE(ACAGI)
#include "AcagiCompositor.h"
#include "Image.h"
#include <wtf/RefPtr.h>

namespace WebCore {

class GraphicsLayer;

void AcagiTile::updateContents(AcagiCompositor* compositor, Image* image, const IntRect& dirtyRect, AcagiBitmapTexture::UpdateContentsFlag updateContentsFlag)
{
    IntRect targetRect = enclosingIntRect(m_tileRect);
    targetRect.intersect(dirtyRect);
    if (targetRect.isEmpty())
        return;
    IntPoint sourceOffset = targetRect.location();

    // Normalize sourceRect to the buffer's coordinates.
    sourceOffset.move(-dirtyRect.x(), -dirtyRect.y());

    // Normalize targetRect to the texture's coordinates.
    targetRect.move(-m_tileRect.x(), -m_tileRect.y());
    if (!m_texture) {
        m_texture = compositor->createTexture();
        m_texture->reset(m_tileRect.size(), image->currentFrameKnownToBeOpaque() ? 0 : AcagiBitmapTexture::SupportsAlpha);
    }

    m_texture->updateContents(image, targetRect, sourceOffset, updateContentsFlag);
}

void AcagiTile::updateContents(AcagiCompositor* compositor, GraphicsLayer* sourceLayer, const IntRect& dirtyRect, AcagiBitmapTexture::UpdateContentsFlag updateContentsFlag)
{
    // Source rect in the contents coordinates.
    FloatRect sourceRect = dirtyRect;
    sourceRect.unite(m_dirtyRect);
    sourceRect.intersect(scaledTileRect());
    m_dirtyRect = IntRect();
    if (sourceRect.isEmpty())
        return;

    // Reset texture.
    if (!m_texture) {
        m_texture = compositor->createTexture();
        m_texture->reset(m_tileRect.size(), AcagiBitmapTexture::SupportsAlpha);
        sourceRect = scaledTileRect();
    } else
        m_texture = compositor->duplicateTexture(m_texture);

    // Calculate dirty rect in the buffer's coordinate.
    FloatRect enclosedTargetRect = sourceRect;
    enclosedTargetRect.scale(1 / m_contentsScale);
    IntRect targetRect = enclosingIntRect(enclosedTargetRect);

    // Update sourceRect by scaling targetRect.
    sourceRect = targetRect;
    sourceRect.scale(1 / m_contentsScale);

    IntPoint targetOffset = m_tileRect.location();
    targetRect.moveBy(-targetOffset);
    
    m_texture->updateContents(compositor, sourceLayer, targetRect, targetOffset, sourceRect, updateContentsFlag);
}

void AcagiTile::paint(AcagiCompositor* compositor, const TransformationMatrix& transform, float opacity, const unsigned exposedEdges)
{
    FloatRect rect = m_tileRect;
    rect.scale(1 / m_contentsScale);
    if (texture().get())
        compositor->drawTexture(*texture().get(), rect, transform, opacity, exposedEdges);
}

} // namespace WebCore
#endif 
